;~%include "borrar_arbol.asm"
%include "cargar_arbol_huffman.asm"
%include "macros.mac"
;int descomprimir_buffer ( unsigned char *src_buf,	unsigned int long_codificacion, unsigned char *dst_buf,	unsigned int dst_size, codigo_t *tabla_codigos )
extern printf
;~extern cargar_arbol_huffman
extern stdout ;para el fflush
extern fflush ;para que el printf imprima bien durante un ciclo
extern borrar_arbol
%define src_buf ebp+8
%define long_codificacion ebp+12
%define dst_buf ebp+16
%define dst_size ebp+20
%define tabla_codigos ebp+24
%define raiz ebp-4
%define ptr_nodo_temp ebp-8
%define porcentaje ebp-12
%define byte_del_buffer ebp-13
%define ptr_dst_orig ebp-17
%define izq 13
%define der 17
%define NULL 0
global descomprimir_buffer


section .data
msj: db 13,"%d%% descomprimido.",0
new_line: db 10,0
section .text

descomprimir_buffer:
	convencion_C 17
	mov eax, [dst_buf]
	mov [ptr_dst_orig],eax
	
	;cargo el arbol huffman
	lea eax, [raiz]
	push eax
	push dword [tabla_codigos]
	call cargar_arbol_huffman
	add esp,8
	cmp eax, 0
	je near arbol_error
	
	;cargo el offset_codificacion desde el header
	;y me muevo hasta la codificacion
	;esto no es lo mismo que [src_buf+12]
	;[src_buf+12] == ebp+8+12   ->mal
	;[src_buf]+12 == (*src_buf)+12  ->bien
	mov eax,[src_buf]
	add eax, 12
	add eax, [eax]
	sub eax, 12
	mov [src_buf],eax

	mov eax, [raiz]
	mov [ptr_nodo_temp],eax
	
	;calculo la cantidad de codificaciones
	;me fijo si es modulo 8, hago un and con 7
	; xxxx xxxx and 0000 0111 == 0 o algo no modulo 8
	mov eax, [long_codificacion]
	mov ebx, eax
	shr ebx, 3
	mov ecx, eax
	and ecx, 7
	cmp ecx, 0
	je mod_8
	inc ebx
	mod_8:
	; ebx => cant_codificaciones

	mov dword [porcentaje], 0
	xor edi,edi ;contador
	ciclo_descomprimir:
		
			;imprimo el porcentaje!
			push eax
			push edx
			xor edx,edx
			;~;total / 100
			mov eax, ebx
			mov esi, 100
			div esi
			cmp eax,0
			je fin_porcentaje
			mov esi,edi
;~
			;~;contador % total (cuando divido, en edx me pone el remainder)
			;~;tengo q hacer un swap con los registros.. =S
			;~;quien dijo que necesito una var temporal para hacer el swap??? >=D
			;~;jajaja  http://en.wikipedia.org/wiki/XOR_swap_algorithm
			xor esi,eax
			xor eax,esi
			xor esi,eax
			cmp eax, 0
			je fin_porcentaje
			div esi
			;~;en edx = i % (cant_codificaciones/100)
			cmp edx, 0
			jne fin_porcentaje
			;~;porcentaje++
			inc dword [porcentaje]
			
			pusha
			push dword [porcentaje]
			push msj
			call printf
			add esp,8
;~
			;~;esto es cierto algo para que me imprima lindo el porcentaje ;)
			push dword [stdout]
			call fflush
			add esp,4

			popa
			
			
;~
			fin_porcentaje:
			pop edx
			pop eax
			;~;fin imprimir porcentaje
			
			;agarro un byte del buffer
			mov eax, [src_buf]
			mov eax, [eax+edi]
			mov [byte_del_buffer], al

			;aca tengo eax=byte buffer, ebx=total, edi =contador
			;saco el reverso del byte
			;hago esta macro para no tener q gastar registros en un loop

			;ecx =para guardar modulo,edx= reverso
			
			xor ecx,ecx
			xor edx,edx
			
			%rep 8
				shl dl,1
				mov cl, byte [byte_del_buffer]
				and cl, 1 ;modulo 2, hago un and con 1
				add dl,cl
				shr byte [byte_del_buffer],1
			
			%endrep
			;tengo el reverso del byte
			mov byte [byte_del_buffer],dl

			;ahora si, calculo lo que voy a escribir
			
			mov ecx,8 ;contador
			
			;esi lo tengo libre..
			loop_escribir_byte:
			xor edx,edx
				mov dl,byte [byte_del_buffer]
				and dl, 1 ;modulo 2, hago un and con 1

				mov esi, [ptr_nodo_temp]
				cmp dl,0
				je es_der
					mov edx, izq
					jmp seguir_rama
				es_der:
					mov edx, der
				
				seguir_rama:
				mov esi, [esi+edx]
				mov esi, [esi+edx]

				cmp esi, NULL
				je poner_en_buf
					;No es hoja, sigo
					mov esi, [ptr_nodo_temp]
					mov esi, [esi+edx]
					mov  [ptr_nodo_temp], esi
					jmp seguir
				poner_en_buf:
					;es hoja

					mov eax, [dst_buf]
					mov esi, [ptr_nodo_temp]
					mov esi, [esi+edx]
					xor edx,edx
					;muevo el simbolo para ponerlo..
					mov dl,byte [esi]
	
					mov byte [eax],dl
					inc dword [dst_buf]
					;apunto a la raiz
					mov eax,[raiz]
					mov [ptr_nodo_temp],eax
				seguir:
					shr byte [byte_del_buffer],1
					loop loop_escribir_byte

			inc edi
			cmp edi,ebx
			jne ciclo_descomprimir

	
	push dword  [raiz]		
	call borrar_arbol
	add esp,4
	push new_line
	call printf
	add esp,4

	mov eax,[ptr_dst_orig]
	mov  [dst_buf],eax

	mov eax, 1
fin_desc_buf:
	convencion_C_fin 17

	ret

arbol_error:
	print_error "No se pudo cargar los datos de descompresion!"
	jmp fin_desc_buf
